package io.hellsinger.vortex.util

import android.os.Environment
import io.hellsinger.filesystem.attribute.DefaultPathAttribute
import io.hellsinger.filesystem.attribute.PathType
import io.hellsinger.filesystem.path.Path
import io.hellsinger.vortex.data.asPath
import io.hellsinger.vortex.data.model.PathItem

interface StoragePathSegmentParser {
    fun parse(
        item: PathItem,
        endpoint: Path = Environment.getExternalStorageDirectory().asPath(),
    ): ArrayList<PathItem>
}

class SpeedStoragePathSegmentParser : StoragePathSegmentParser {
    override fun parse(
        item: PathItem,
        endpoint: Path,
    ): ArrayList<PathItem> {
        if (item.path == endpoint) {
            return arrayListOf(item)
        }
        val segments = arrayListOf<PathItem>()
        var cPath = item.path

        // TODO: Replace with for loop, exclude cPath variable and reverse() method
        while (cPath != endpoint.parent) {
            segments += PathItem(cPath, DefaultPathAttribute(type = PathType.Directory))
            cPath = cPath.parent ?: break
        }

        segments.reverse()

        return segments
    }
}

class MemoryStoragePathSegmentParser : StoragePathSegmentParser {
    override fun parse(
        item: PathItem,
        endpoint: Path,
    ): ArrayList<PathItem> {
        if (item.path == endpoint) return arrayListOf(PathItem(item))

        /**
         *  Memory VS Speed
         *  Next lines describes how much we need to allocate memory to put
         *  path segments into list, so basically we just checking
         *  if segments of path don't get away from
         *  [Environment.getExternalStorageDirectory] path
         *  **/
        val size = item.path.nameCount - 1
        var count = 0
        for (i in size downTo 0) {
            val parent = item.path.getParentAt(i) ?: break
            if (parent != endpoint.parent) {
                count++
            } else {
                break
            }
        }

        val segments = ArrayList<PathItem>(count + 1)
        while (count >= 0) {
            segments.add(
                PathItem(
                    item.path.getParentAt(item.path.nameCount - count--) ?: item.path,
                    DefaultPathAttribute(type = PathType.Directory),
                ),
            )
        }

        return segments
    }
}
